using System;
using System.Drawing;

namespace NobleTech.Products.CreatureKingdom.Utils
{
    public struct SizeD
    {
        public double Width, Height;

        public SizeD(double Width, double Height)
        {
            this.Width = Width;
            this.Height = Height;
        }

        public static SizeD FromAngle(double Angle, double Length)
        {
            return new SizeD(Math.Sin(Angle) * Length, Math.Cos(Angle) * Length);
        }

        public static explicit operator SizeF(SizeD size)
        {
            return new SizeF((float)size.Width, (float)size.Height);
        }

        public static implicit operator SizeD(SizeF size)
        {
            return new SizeD(size.Width, size.Height);
        }

        public static implicit operator SizeD(Size size)
        {
            return new SizeD(size.Width, size.Height);
        }

        public override string ToString()
        {
            return string.Format("({0}, {1})", Width, Height);
        }

        public override int GetHashCode()
        {
            return Width.GetHashCode() ^ Height.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj is SizeD)
                return this == (SizeD)obj;
            return ((SizeF)this).Equals(obj);
        }

        public static bool operator ==(SizeD a, SizeD b)
        {
            return a.Width == b.Width && a.Height == b.Height;
        }
        public static bool operator !=(SizeD a, SizeD b) { return !(a == b); }

        public static SizeD operator +(SizeD size1, SizeD size2)
        {
            return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
        }

        public static SizeD operator -(SizeD size1, SizeD size2)
        {
            return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
        }

        public static SizeD operator *(double x, SizeD v) { return new SizeD(v.Width * x, v.Height * x); }
        public static SizeD operator *(SizeD v, double x) { return x * v; }
        public static SizeD operator /(SizeD v, double x) { return new SizeD(v.Width / x, v.Height / x); }
        public static SizeD operator %(SizeD v, double x) { return new SizeD(v.Width % x, v.Height % x); }

        public double Length { get { return Math.Sqrt(Width * Width + Height * Height); } }
        public double Angle { get { return Misc.NormaliseAngle(Math.Atan2(Width, Height)); } }
    }
}
